#include "Blob.h"
#include "Image.h"
#include <string>
#include <cctype>

using namespace std;
namespace Magick
{
	void Blob::setData(IplImage* image, const std::string& channelSeq)
	{
		string dstSeq = channelSeq;
		for (int i = 0; i < dstSeq.length(); ++i){
			dstSeq[i] = toupper(dstSeq[i]);
		}
		if (dstSeq != "RGBA" && dstSeq != "RGB"){
			throw Error(("target seq: " + dstSeq + " not supported").c_str());
		}
		string srcSeq(image->channelSeq, image->channelSeq + image->nChannels);
		for (int i = 0; i < srcSeq.length(); ++i){
			srcSeq[i] = toupper(srcSeq[i]);
		}
		if (srcSeq != "RGBA" && srcSeq != "RGB" && srcSeq != "BGRA" && srcSeq != "BGR"){
			throw Error(("source seq: " + srcSeq + " not supported").c_str());
		}

		int mp[4] = { -1, -1, -1, -1 };
		for (int i = 0; i < dstSeq.size(); ++i){
			for (int j = 0; j < srcSeq.size(); ++j){
				if (dstSeq[i] == srcSeq[j]){
					mp[i] = j;
				}
			}
		}

		unsigned char* pSrc = (unsigned char*)image->imageData;
		unsigned char* pDst = new unsigned char[image->width*image->height*dstSeq.length()];
		for (int r = 0; r < image->height; ++r){
			for (int c = 0; c < image->width; ++c){
				int offsetSrc = image->widthStep*r + image->nChannels*c;
				int offsetDst = dstSeq.length()*(image->width*r + c);
				unsigned char* pS = pSrc + offsetSrc;
				unsigned char* pD = pDst + offsetDst;
				for (int channelID = 0; channelID < dstSeq.length(); ++channelID){
					if (mp[channelID] != -1){
						*(pD + channelID) = *(pS + mp[channelID]);
					}
					else{
						if (dstSeq[channelID] == 'A'){
							*(pD + channelID) = 255;
						}
						else{
							*(pD + channelID) = 0;
						}
					}
				}
			}
		}

		if (_data != nullptr)
		{
			delete[] _data;
		}
		_data = (const void *)pDst;
	}
}